/**
 *
 */
package org.tio.http.apitool.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.util.StrUtil;

/**
 * @filename: com.talent.util.HttpClientUtils
 * @copyright: Copyright (c)2010
 * @company: talent
 * @author: 谭耀武
 * @version: 1.0
 * @create time: 2012-5-31 上午9:26:39
 * @record <table cellPadding="3" cellSpacing="0" style="width:600px">
 * <thead style="font-weight:bold;background-color:#e3e197">
 * <tr>   <td>date</td>	<td>author</td>		<td>version</td>	<td>description</td></tr>
 * </thead>
 * <tbody style="background-color:#ffffeb">
 * <tr><td>2012-5-31</td>	<td>谭耀武</td>	<td>1.0</td>	<td>create</td></tr>
 * </tbody>
 * </table>
 */
public class HttpClientUtils {
	//    private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);

	public static final String encoding = "utf-8";

	private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);

	private static AtomicLong requestSeq = new AtomicLong();

	/**
	 * 将set-cookie转换成cookie
	 *
	 * @param setCookieHeaders
	 * @return
	 */
	//	public static List<Header> convertSetCookieToCookie(Header[] setCookieHeaders)
	//	{
	//		List<Header> cookieHeaders = null;
	//		if (setCookieHeaders != null)
	//		{
	//			cookieHeaders = new ArrayList<Header>();
	//			if (setCookieHeaders != null && setCookieHeaders.length > 0)
	//			{
	//				for (Header _header : setCookieHeaders)
	//				{
	//
	//					cookieHeaders.add(new BasicHeader("Cookie", _header.getValue()));
	//				}
	//			}
	//		}
	//		return cookieHeaders;
	//	}

	/**
	* 将set-cookie转换成cookie
	*
	* @param setCookieHeaders
	* @return
	*/
	public static List<Header> convertSetCookieToCookie(Header[] setCookieHeaders) {
		List<Header> cookieHeaders = null;
		if (setCookieHeaders != null) {
			cookieHeaders = new ArrayList<Header>();
			if (setCookieHeaders != null && setCookieHeaders.length > 0) {
				for (Header _header : setCookieHeaders) {

					cookieHeaders.add(new BasicHeader("Cookie", _header.getValue()));
				}
			}
		}
		return cookieHeaders;
	}

	public static List<Header> getCookieHeaders(HttpResponse response) throws Exception {
		Header[] setCookieHeaders = response.getHeaders("Set-Cookie");
		List<Header> _cookieHeaders = convertSetCookieToCookie(setCookieHeaders);
		return _cookieHeaders;
	}

	/**
	 * 获取cookie头
	 *
	 * @param requestParams
	 * @param url
	 * @param headers
	 * @param method
	 * @param proxy
	 * @return
	 * @throws Exception
	 */
	public static List<Header> getCookieHeaders(Map<String, Object> requestParams, String url, List<Header> headers, String method, HttpHost proxy) throws Exception {
		HttpResponse response = null;
		List<Header> cookieHeaders = new ArrayList<Header>();
		if (headers == null) {
			headers = new ArrayList<Header>();
		}

		while (true) {
			if ("get".equalsIgnoreCase(method)) {
				response = HttpClientUtils.get(url, headers, proxy);
			} else {
				response = HttpClientUtils.post(url, requestParams, headers, proxy);
			}

			StatusLine statusLine = response.getStatusLine();

			List<Header> headers1 = getCookieHeaders(response);
			if (headers1 != null) {
				headers.addAll(headers1);
				cookieHeaders.addAll(headers1);
			}

			if (statusLine.getStatusCode() == 302) //重定向
			{
				Header[] locationHeader = response.getHeaders("Location");
				url = locationHeader[0].getValue();
				continue;
			} else {
				break;
			}
		}
		return cookieHeaders;
	}

	public static HttpResponse get(String url, List<Header> headers, HttpHost proxy) throws Exception {
		Map<String, Object> map = new HashMap<>();
		headersToMap(headers, map);

		return get(url, map, proxy);
	}
	
	public static HttpResponse post(String url, Map<String, Object> requestParams, List<Header> headers, HttpHost proxy) throws Exception {
		Map<String, Object> map = new HashMap<>();
		headersToMap(headers, map);

		return post(url, requestParams, map, proxy);
	}

	/**
	 * @param method
	 * @return
	 */
	public static HttpRequestBase createHttpRequestBaseByMethod(String method) {
		HttpRequestBase ret = null;
		if (HttpGet.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpGet();
		} else if (HttpPost.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpPost();
		} else if (HttpDelete.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpDelete();
		} else if (HttpHead.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpHead();
		} else if (HttpOptions.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpOptions();
		} else if (HttpTrace.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpTrace();
		} else if (HttpPut.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpPut();
		} else if (HttpPatch.METHOD_NAME.equalsIgnoreCase(method)) {
			ret = new HttpPatch();
		}
		return ret;
	}

	public static CloseableHttpClient createSSLClientDefault() {
		try {
			SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				//信任所有
				public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}
			}).build();
			//			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
			SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(sslContext, org.apache.http.conn.ssl.NoopHostnameVerifier.INSTANCE);
			return HttpClients.custom().setSSLSocketFactory(ssf).build();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}

	public static HttpResponse delete(String url, String requestBody, Map<String, Object> headers, HttpHost proxy, int timeout) throws ClientProtocolException, IOException {
		return httpRequest(url, null, headers, proxy, "delete", requestBody, timeout);
	}

	/**
	 * 
	 * @param url
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @author: tanyaowu
	 * @创建时间:　2016年6月24日 下午2:51:05
	 */
	public static HttpResponse get(String url) throws ClientProtocolException, IOException {
		return get(url, (Map<String, Object>) null, (HttpHost) null);
	}

	//	public static HttpResponse get(String url, Map<String, Object> headers, HttpHost proxy, int timeout) throws ClientProtocolException, IOException
	//	{
	//		return httpRequest(url, null, headers, proxy, "get", timeout);
	//	}

	/**
	 * 
	 * @param url
	 * @param headers
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @author: tanyaowu
	 * @创建时间:　2016年6月24日 下午2:50:59
	 */
	public static HttpResponse get(String url, Map<String, Object> headers) throws ClientProtocolException, IOException {
		return get(url, headers, (HttpHost) null);
	}

	/**
	 * 
	 * @param url
	 * @param headers
	 * @param proxy
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @author: tanyaowu
	 * @创建时间:　2016年6月24日 下午2:50:51
	 */
	public static HttpResponse get(String url, Map<String, Object> headers, HttpHost proxy) throws ClientProtocolException, IOException {
		return get(url, headers, proxy, 5000);
	}

	/**
	 * @param url
	 * @param headers
	 * @param proxy
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	//	public static HttpResponse get(String url, Map<String, Object> headers, HttpHost proxy) throws ClientProtocolException, IOException
	//	{
	//		return get(url, headers, proxy, 100000);
	//	}

	public static HttpResponse get(String url, Map<String, Object> headers, HttpHost proxy, int timeout) throws ClientProtocolException, IOException {

		return httpRequest(url, null, headers, proxy, "get", timeout);
	}

	public static Map<String, String> getCookies(HttpResponse response) throws Exception {
		Map<String, String> ret = null;
		Header[] setCookieHeaders = response.getHeaders("Set-Cookie");
		if (setCookieHeaders != null && setCookieHeaders.length > 0) {
			ret = new HashMap<>();
			for (Header header : setCookieHeaders) {
				String _value = header.getValue();
				String[] strings = StrUtil.split(_value, ";");
				strings = StrUtil.split(strings[0], "=");
				ret.put(strings[0], strings[1]);
			}
		}
		return ret;
	}

	public static String getCookiestr(HttpResponse response) throws Exception {
		Map<String, String> cookies = getCookies(response);
		String cookiestr = "";
		Set<Entry<String, String>> set = cookies.entrySet();
		for (Entry<String, String> entry : set) {
			cookiestr += entry.getKey() + "=" + entry.getValue() + "; ";
		}
		cookiestr = cookiestr.substring(0, cookiestr.length() - 2);
		return cookiestr;
	}

	public static String getCookiestr(Map<String, String> cookies) throws Exception {
		String cookiestr = "";
		Set<Entry<String, String>> set = cookies.entrySet();
		for (Entry<String, String> entry : set) {
			cookiestr += entry.getKey() + "=" + entry.getValue() + "; ";
		}
		cookiestr = cookiestr.substring(0, cookiestr.length() - 2);
		return cookiestr;
	}

	//	/**
	//	 * 获取cookie头
	//	 *
	//	 * @param requestParams
	//	 * @param url
	//	 * @param headers
	//	 * @param method
	//	 * @param proxy
	//	 * @return
	//	 * @throws Exception
	//	 */
	//	public static List<Header> getCookieHeaders(Map<String, Object> requestParams, String url, Map<String, Object> _headers, String method, HttpHost proxy) throws Exception
	//	{
	//		HttpResponse response = null;
	//		//		List<Header> headers = mapToHeaders(_headers);
	//		List<Header> cookieHeaders = new ArrayList<Header>();
	//		//		if (headers == null)
	//		//		{
	//		//			headers = new ArrayList<Header>();
	//		//		}
	//
	//		while (true)
	//		{
	//			if ("get".equalsIgnoreCase(method))
	//			{
	//				response = HttpClientUtils.get(url, _headers, proxy);
	//			} else
	//			{
	//				response = HttpClientUtils.post(url, requestParams, _headers, proxy);
	//			}
	//
	//			StatusLine statusLine = response.getStatusLine();
	//
	//			List<Header> headers1 = getCookieHeaders(response);
	//			if (headers1 != null)
	//			{
	//				//				headers.addAll(headers1);
	//				cookieHeaders.addAll(headers1);
	//			}
	//
	//			if (statusLine.getStatusCode() == 302) //重定向
	//			{
	//				Header[] locationHeader = response.getHeaders("Location");
	//				url = locationHeader[0].getValue();
	//				continue;
	//			} else
	//			{
	//				break;
	//			}
	//		}
	//		return cookieHeaders;
	//	}

	public static void headersToMap(List<Header> headers, Map<String, Object> map) {
		if (headers != null) {
			for (Header header : headers) {
				map.put(header.getName(), header.getValue());
			}
		}
	}

	public static HttpResponse httpRequest(String uri, Map<String, Object> requestParams, Map<String, Object> headers, HttpHost proxy, String method)
	        throws ClientProtocolException, IOException {
		return httpRequest(uri, requestParams, headers, proxy, method, null);
	}

	public static HttpResponse httpRequest(String uri, Map<String, Object> requestParams, Map<String, Object> requestHeaders, HttpHost proxy, String method, int timeout)
	        throws ClientProtocolException, IOException {
		return httpRequest(uri, requestParams, requestHeaders, proxy, method, null, timeout);
	}

	public static HttpResponse httpRequest(String uri, Map<String, Object> requestParams, Map<String, Object> headers, HttpHost proxy, String method, String requestBody)
	        throws ClientProtocolException, IOException {
		return httpRequest(uri, requestParams, headers, proxy, method, requestBody, 10000);
	}

	public static HttpResponse httpRequest(String uri, Map<String, Object> requestParams, Map<String, Object> requestHeaders, HttpHost proxy, String method, String requestBody,
	        int timeout) throws ClientProtocolException, IOException {

		List<Header> headers = mapToHeaders(requestHeaders);

		long seq = requestSeq.incrementAndGet();

		CloseableHttpClient httpclient;

		if (uri.startsWith("https")) {
			httpclient = HttpClientUtils.createSSLClientDefault();
		} else {
			httpclient = HttpClients.createDefault();
		}

		//		HttpClientContext context = HttpClientContext.create();
		//		httpclient
		//				.getParams()
		//				.setParameter("User-Agent",
		//						"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11");
		HttpRequestBase httpRequestBase = createHttpRequestBaseByMethod(method);
		httpRequestBase.setURI(URI.create(uri));

		CloseableHttpResponse response = null;
		try {
			if (log.isInfoEnabled()) {
				StringBuilder sb4headers = new StringBuilder();
				if (headers != null) {
					sb4headers.append("\r\n[\r\n");
					for (Header header : headers) {
						sb4headers.append("{").append(header.getName()).append("  :  ");
						sb4headers.append(header.getValue()).append("}\r\n");
					}
					sb4headers.append("]\r\n");
				}

				StringBuilder sb4requestparams = new StringBuilder();
				if (requestParams != null) {
					sb4requestparams.append("\r\n[\r\n");
					Set<Map.Entry<String, Object>> entrySet = requestParams.entrySet();
					for (Map.Entry<String, Object> entry : entrySet) {
						sb4requestparams.append("{").append(entry.getKey()).append("  :  ");
						sb4requestparams.append(entry.getValue()).append("}\r\n");
					}
					sb4requestparams.append("]\r\n");
				}

				StringBuilder sb4cookies = new StringBuilder();

				log.info("request url {}:{}, \r\nheaders:{} \r\ncookies:{} \r\nrequestParams:{} \r\nrequestBody:{}", seq, uri, sb4headers, sb4cookies, sb4requestparams,
				        requestBody);
			}

			headers = perfectHeader(headers);
			if (headers != null) {

				headers.forEach(header -> {
					httpRequestBase.addHeader(header);
				});

				//                for (Header header : headers)
				//                {
				//                    httpRequestBase.addHeader(header);
				//                }
			}

			List<NameValuePair> nameValuePairs = null;// new ArrayList<NameValuePair>();

			if (requestParams != null) {
				nameValuePairs = new ArrayList<NameValuePair>();
				Set<Map.Entry<String, Object>> entrySet = requestParams.entrySet();

				for (Map.Entry<String, Object> entry : entrySet) {
					Object entryValue = entry.getValue();
					if (entryValue instanceof List) {
						@SuppressWarnings({ "unchecked", "rawtypes" })
						List<String> list = (List) entryValue;
						for (String str : list) {
							nameValuePairs.add(new BasicNameValuePair(entry.getKey(), str));
						}
					} else {
						if (entryValue != null) {
							nameValuePairs.add(new BasicNameValuePair(entry.getKey(), "" + entryValue));
						}
					}

				}
			}
			if (nameValuePairs != null) {
				if (httpRequestBase instanceof HttpPost) {
					UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nameValuePairs, encoding);
					((HttpPost) httpRequestBase).setEntity(entity);
				}
			}

			if (requestBody != null) {
				if (httpRequestBase instanceof HttpEntityEnclosingRequestBase) {
					StringEntity entity = new StringEntity(requestBody, encoding);
					//					 entity.setContentEncoding(encoding);
					//		             entity.setContentType("application/json");
					((HttpEntityEnclosingRequestBase) httpRequestBase).setEntity(entity);
				} else {
					throw new RuntimeException("发送请求体时，必须用post!");
				}
			}
			RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).setConnectTimeout(timeout).setProxy(proxy).build();

			httpRequestBase.setConfig(requestConfig);

			response = httpclient.execute(httpRequestBase);
			if (log.isInfoEnabled()) {
				log.info("response {}:{}", seq, response);
			}
			return response;

		} finally {
			//			if (response != null)
			//			{
			//				response.close();
			//			}
		}

	}

	public static void main(String[] args) throws Exception {
		HttpResponse httpResponse = HttpClientUtils.get("http://www.iteye.com/upload/logo/user/14604/ab265142-9ca8-31b2-a99c-2b1181ae0d38.jpg?1236832266");
		FileOutputStream outstream = new FileOutputStream(new File("c:/xxx.jpg"));
		httpResponse.getEntity().writeTo(outstream);

		//        java.util.concurrent.atomic.AtomicInteger dd = new AtomicInteger(100);
		//        dd.getAndAdd(-1000);
		//        System.out.println(dd.get());

		//		for (int i = 0; i < 18000; i++){
		//			try
		//			{
		//				System.out.println(i);
		//				String url1 = "http://test.154.51rexiu.cn:9321";
		//				HttpResponse httpResponse1 = get(url1);
		//
		//			} catch (Exception e)
		//			{
		//				log.error(e.toString(), e);
		//			}
		//		}

		//		User-Agent在iPhone微信下，返回
		//		Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B176 MicroMessenger/4.3.2
		//		User-Agent在Android微信下，返回
		//		Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5
		// .255

		//		for (int i = 0; i < 500; i++){
		//			try
		//			{
		//				String url1 = "http://m.mjiajia.cn/index.php?m=home&c=vote&a=index&id=5&from=timeline&isappinstalled=0";
		//				HttpResponse httpResponse1 = get(url1);
		//
		//				String url = "http://m.mjiajia.cn/index.php?m=home&c=vote&a=tou&id=5&oid=58";
		//				List<Header> cookies = getCookieHeaders(httpResponse1);
		//				Header phpheader = new BasicHeader("Cookie", "thinkphp_show_page_trace=0|0");
		//				cookies.add(phpheader);
		//				Header header1 = new BasicHeader("Referer", "http://m.mjiajia.cn/index.php?m=home&c=vote&a=index&id=5&from=timeline&isappinstalled=0");
		//				cookies.add(header1);
		//				Header header2 = new BasicHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like
		// Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5.255");
		//				cookies.add(header2);
		//
		//
		//
		//				Map<String, Object> requestParams = new HashMap<>();
		//				requestParams.put("id", 5);
		//				requestParams.put("oid", 58);//康
		////				requestParams.put("oid", 60);//3
		//				HttpResponse httpResponse = post(url, requestParams, cookies, null);
		//				String responseHtml = EntityUtils.toString(httpResponse.getEntity(), Charset.forName("utf-8"));
		////				System.out.println(responseHtml);
		//			} catch (Exception e)
		//			{
		//				log.error(e.toString(), e);
		//			}
		//		}

	}

	/**
	 * @param requestHeaders
	 * @return
	 */
	public static List<Header> mapToHeaders(Map<String, Object> requestHeaders) {
		List<Header> headers = null;
		if (requestHeaders != null && requestHeaders.size() > 0) {
			headers = new ArrayList<Header>();
			Set<Entry<String, Object>> entrySet = requestHeaders.entrySet();

			for (Entry<String, Object> entry : entrySet) {
				headers.add(new BasicHeader(entry.getKey(), (String) entry.getValue()));
			}
		}
		return headers;
	}

	public static List<Header> perfectHeader(List<Header> headers) {
		if (headers == null) {
			headers = new ArrayList<Header>();
		}
		//		Header h = null;
		//		h = new BasicHeader("Accept-Encoding", "gzip, deflate");
		//		        headers.add(h);

		//		h = new BasicHeader("User-Agent",
		//				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11");
		//		headers.add(h);
		//
		//        h = new BasicHeader("Accept-Language", "zh-CN");
		//        headers.add(h);

		//        h = new BasicHeader("Referer", "http://as.cnsuning.com/login.htm");   //告诉服务器我是从哪个页面链接过来的
		//        headers.add(h);

		//        h = new BasicHeader("Accept-Language", "zh-CN");
		//        headers.add(h);

		return headers;
	}

	public static HttpResponse post(String url, Map<String, Object> requestParams) throws ClientProtocolException, IOException {
		return post(url, requestParams, (Map<String, Object>) null, (HttpHost) null);
	}

	/**
	 * @param url
	 * @param requestParams
	 * @param headers
	 * @param proxy
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	//	public static HttpResponse post(String url, Map<String, Object> requestParams, Map<String, Object> headers, HttpHost proxy) throws ClientProtocolException, IOException
	//	{
	//		return httpRequest(url, requestParams, headers, proxy, "post");
	//	}

	//	public static HttpResponse post(String url, Map<String, Object> requestParams, Map<String, Object> headers, HttpHost proxy, int timeout) throws ClientProtocolException, IOException
	//	{
	//		return httpRequest(url, requestParams, headers, proxy, "post", timeout);
	//	}

	public static HttpResponse post(String url, Map<String, Object> requestParams, Map<String, Object> headers) throws ClientProtocolException, IOException {
		return post(url, requestParams, headers, null, 5000);
	}

	public static HttpResponse post(String url, Map<String, Object> requestParams, Map<String, Object> requestHeaders, HttpHost proxy) throws ClientProtocolException, IOException {
		return post(url, requestParams, requestHeaders, proxy, 10000);
	}

	public static HttpResponse post(String url, Map<String, Object> requestParams, Map<String, Object> headers, HttpHost proxy, int timeout)
	        throws ClientProtocolException, IOException {
		return httpRequest(url, requestParams, headers, proxy, "post", timeout);
	}

	public static HttpResponse post(String url, String requestBody, Map<String, Object> requestHeaders) throws ClientProtocolException, IOException {
		return post(url, requestBody, requestHeaders, null, 10000);
	}

	public static HttpResponse post(String url, String requestBody, Map<String, Object> requestHeaders, HttpHost proxy) throws ClientProtocolException, IOException {
		return post(url, requestBody, requestHeaders, proxy, 10000);
	}

	public static HttpResponse post(String url, String requestBody, Map<String, Object> headers, HttpHost proxy, int timeout) throws ClientProtocolException, IOException {
		return httpRequest(url, null, headers, proxy, "post", requestBody, timeout);
	}

	public static String toStr(HttpResponse httpResponse) throws Exception {
		return toStr(httpResponse, "utf-8");
	}

	public static String toStr(HttpResponse httpResponse, String charset) throws Exception {
		if (httpResponse == null) {
			return null;
		}
		String responseHtml = EntityUtils.toString(httpResponse.getEntity(), Charset.forName(charset));
		return responseHtml;
	}

	public static String toStr(StatusLine statusLine) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append(statusLine.getProtocolVersion().getProtocol()).append(" ").append(statusLine.getProtocolVersion().getMajor()).append(".")
		        .append(statusLine.getProtocolVersion().getMinor());
		sb.append(" ").append(statusLine.getStatusCode());
		sb.append(" ").append(statusLine.getReasonPhrase());
		return sb.toString();
	}

	/**
	 * 把请求头wrap一下，使之变成patch请求
	 * @param headers
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @author: tanyaowu
	 * @创建时间:　2016年6月24日 下午2:33:01
	 */
	public static Map<String, Object> wrapToPatch(Map<String, Object> headers) {
		if (headers == null) {
			headers = new HashMap<String, Object>();
		}
		headers.put("x-http-method-override", "PATCH");
		return headers;
	}

	/**
	 *
	 */
	public HttpClientUtils() {

	}

	protected ConnectionSocketFactory createDefaultSecureSocketFactory() {
		try {
			SSLContext ctx = SSLContext.getInstance("SSL");
			X509TrustManager tm = new X509TrustManager() {
				public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
					return;
				}

				public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
					return;
				}

				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			};
			ctx.init(null, new TrustManager[] { tm }, null);
			@SuppressWarnings("deprecation")
			final SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			return ssf;
		} catch (NoSuchAlgorithmException e) {
			log.error("SSL Connection Failure!", 10003, e);
		} catch (KeyManagementException e) {
			log.error("SSL Connection Failure!", 10003, e);
		}

		return SSLConnectionSocketFactory.getSocketFactory();
	}
}